import * as Cesium from 'cesium';

export class Event {
  constructor(cesiumManager) {
    this.cesiumManager = cesiumManager;
    this.drawHandler = null;
    
    // 初始化事件处理器容器
    this.eventHandlers = {
      mouse: new Map(),     // 鼠标事件
      camera: new Map(),    // 相机事件
      keyboard: new Map(),  // 键盘事件
      scene: new Map()      // 场景事件
    };
    
    // 创建屏幕空间事件处理器
    if (this.cesiumManager && this.cesiumManager.viewer) {
      this.screenSpaceEventHandler = new Cesium.ScreenSpaceEventHandler(
        this.cesiumManager.viewer.scene.canvas
      );
    }
  }
  
  /**
   * 添加鼠标事件监听器
   * @param {String} eventType - 事件类型，如 'LEFT_CLICK', 'RIGHT_CLICK' 等
   * @param {Function} callback - 回调函数
   * @param {Object} options - 可选参数
   */
  addMouseEventListener(eventType, callback, options = {}) {
    if (!this.screenSpaceEventHandler) return;
    
    const cesiumEventType = Cesium.ScreenSpaceEventType[eventType];
    if (!cesiumEventType) {
      console.warn(`Invalid mouse event type: ${eventType}`);
      return;
    }
    
    // 注销已存在的同类型事件
    if (this.eventHandlers.mouse.has(eventType)) {
      this.removeMouseEventListener(eventType);
    }
    
    // 添加事件监听
    this.screenSpaceEventHandler.setInputAction(callback, cesiumEventType, options.modifier);
    
    // 保存事件处理器引用以便后续清理
    this.eventHandlers.mouse.set(eventType, {
      callback,
      eventType: cesiumEventType,
      modifier: options.modifier
    });
  }
  
  /**
   * 移除鼠标事件监听器
   * @param {String} eventType - 事件类型
   */
  removeMouseEventListener(eventType) {
    if (!this.screenSpaceEventHandler || !this.eventHandlers.mouse.has(eventType)) return;
    
    const handler = this.eventHandlers.mouse.get(eventType);
    this.screenSpaceEventHandler.removeInputAction(handler.eventType, handler.modifier);
    this.eventHandlers.mouse.delete(eventType);
  }
  
  /**
   * 添加键盘事件监听器
   * @param {String} eventType - 事件类型 ('keydown', 'keyup')
   * @param {Function} callback - 回调函数
   */
  addKeyboardEventListener(eventType, callback) {
    if (!document || (eventType !== 'keydown' && eventType !== 'keyup')) return;
    
    // 注销已存在的同类型事件
    if (this.eventHandlers.keyboard.has(eventType)) {
      this.removeKeyboardEventListener(eventType);
    }
    
    // 添加事件监听
    document.addEventListener(eventType, callback);
    
    // 保存事件处理器引用
    this.eventHandlers.keyboard.set(eventType, callback);
  }
  
  /**
   * 移除键盘事件监听器
   * @param {String} eventType - 事件类型
   */
  removeKeyboardEventListener(eventType) {
    if (!document || !this.eventHandlers.keyboard.has(eventType)) return;
    
    const handler = this.eventHandlers.keyboard.get(eventType);
    document.removeEventListener(eventType, handler);
    this.eventHandlers.keyboard.delete(eventType);
  }
  
  /**
   * 添加相机事件监听器
   * @param {String} eventType - 事件类型 ('moveStart', 'moveEnd', 'changed')
   * @param {Function} callback - 回调函数
   */
  addCameraEventListener(eventType, callback) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) return;
    
    const camera = this.cesiumManager.viewer.camera;
    if (!camera[eventType] || typeof camera[eventType].addEventListener !== 'function') {
      console.warn(`Invalid camera event type: ${eventType}`);
      return;
    }
    
    // 注销已存在的同类型事件
    if (this.eventHandlers.camera.has(eventType)) {
      this.removeCameraEventListener(eventType);
    }
    
    // 添加事件监听
    camera[eventType].addEventListener(callback);
    
    // 保存事件处理器引用
    this.eventHandlers.camera.set(eventType, callback);
  }
  
  /**
   * 移除相机事件监听器
   * @param {String} eventType - 事件类型
   */
  removeCameraEventListener(eventType) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) return;
    
    const camera = this.cesiumManager.viewer.camera;
    if (!this.eventHandlers.camera.has(eventType)) return;
    
    const handler = this.eventHandlers.camera.get(eventType);
    camera[eventType].removeEventListener(handler);
    this.eventHandlers.camera.delete(eventType);
  }
  
  /**
   * 添加场景事件监听器
   * @param {String} eventType - 事件类型 ('postRender', 'preRender', 'renderError' 等)
   * @param {Function} callback - 回调函数
   */
  addSceneEventListener(eventType, callback) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) return;
    
    const scene = this.cesiumManager.viewer.scene;
    if (!scene[eventType] || typeof scene[eventType].addEventListener !== 'function') {
      console.warn(`Invalid scene event type: ${eventType}`);
      return;
    }
    
    // 注销已存在的同类型事件
    if (this.eventHandlers.scene.has(eventType)) {
      this.removeSceneEventListener(eventType);
    }
    
    // 添加事件监听
    scene[eventType].addEventListener(callback);
    
    // 保存事件处理器引用
    this.eventHandlers.scene.set(eventType, callback);
  }
  
  /**
   * 移除场景事件监听器
   * @param {String} eventType - 事件类型
   */
  removeSceneEventListener(eventType) {
    if (!this.cesiumManager || !this.cesiumManager.viewer) return;
    
    const scene = this.cesiumManager.viewer.scene;
    if (!this.eventHandlers.scene.has(eventType)) return;
    
    const handler = this.eventHandlers.scene.get(eventType);
    scene[eventType].removeEventListener(handler);
    this.eventHandlers.scene.delete(eventType);
  }
  
  /**
   * 销毁所有事件监听器
   */
  destroy() {
    // 移除所有鼠标事件
    for (const eventType of this.eventHandlers.mouse.keys()) {
      this.removeMouseEventListener(eventType);
    }
    
    // 移除所有键盘事件
    for (const eventType of this.eventHandlers.keyboard.keys()) {
      this.removeKeyboardEventListener(eventType);
    }
    
    // 移除所有相机事件
    for (const eventType of this.eventHandlers.camera.keys()) {
      this.removeCameraEventListener(eventType);
    }
    
    // 移除所有场景事件
    for (const eventType of this.eventHandlers.scene.keys()) {
      this.removeSceneEventListener(eventType);
    }
    
    // 销毁屏幕空间事件处理器
    if (this.screenSpaceEventHandler) {
      this.screenSpaceEventHandler.destroy();
      this.screenSpaceEventHandler = null;
    }
    
    // 清空所有事件处理器容器
    this.eventHandlers.mouse.clear();
    this.eventHandlers.keyboard.clear();
    this.eventHandlers.camera.clear();
    this.eventHandlers.scene.clear();
  }
}